unit uTransferVideo;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, StrUtils,
  Dialogs, Grids, AdvObj, BaseGrid, AdvGrid, AdvCGrid, spSkinShellCtrls, uDM,xVideo,
  SkinCtrls, StdCtrls, Mask, SkinBoxCtrls, DynamicSkinForm, ccedlink, ComCtrls,
  ExtCtrls, Menus, SkinMenus;

type
  TFrmTransferVideo = class(TForm)
    grid: TAdvStringGrid;
    OD: TspSkinOpenDialog;
    btnPlay: TspSkinButton;
    btnStop: TspSkinButton;
    spSkinStdLabel1: TspSkinStdLabel;
    ServerDir: TspSkinDirectoryEdit;
    Posisi: TspSkinTrackBar;
    spDynamicSkinForm1: TspDynamicSkinForm;
    btnTransfer: TspSkinButton;
    gauge: TspSkinGauge;
    ColumnComboEditLink3: TColumnComboEditLink;
    Display: TProgressBar;
    spSkinStdLabel2: TspSkinStdLabel;
    spSkinStdLabel3: TspSkinStdLabel;
    Timer1: TTimer;
    Volume1: TspSkinSlider;
    spSkinStdLabel4: TspSkinStdLabel;
    Panel1: TPanel;
    RBLeft: TRadioButton;
    RBRight: TRadioButton;
    RadioButton1: TRadioButton;
    spSkinStdLabel5: TspSkinStdLabel;
    spSkinPopupMenu1: TspSkinPopupMenu;
    Hapus1Baris1: TMenuItem;
    HapusSemuaBaris1: TMenuItem;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormShow(Sender: TObject);
    procedure gridCanEditCell(Sender: TObject; ARow, ACol: Integer;
      var CanEdit: Boolean);
    procedure gridGetEditorType(Sender: TObject; ACol, ARow: Integer;
      var AEditor: TEditorType);
    procedure gridKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure btnTransferClick(Sender: TObject);
    procedure gridGetEditorProp(Sender: TObject; ACol, ARow: Integer;
      AEditLink: TEditLink);
    procedure btnPlayClick(Sender: TObject);
    procedure btnStopClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure PosisiLastChange(Sender: TObject);
    procedure Volume1Change(Sender: TObject);
    procedure RBLeftClick(Sender: TObject);
    procedure RBRightClick(Sender: TObject);
    procedure RadioButton1Click(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure Hapus1Baris1Click(Sender: TObject);
    procedure HapusSemuaBaris1Click(Sender: TObject);
  private
    { Private declarations }
    chan : HSTREAM;
    
    procedure initForm;
    procedure initGrid;
    procedure setColWidth;
    function isValid: boolean;
    function issaved: boolean;
    function getAttrib: byte;
    
    procedure startProgress;
    procedure prosessProgress(dataCount, progress: integer);
    procedure endProgress;

  public
    { Public declarations }
  end;

  PProgressbar = ^TProgressBar;

var
  FrmTransferVideo: TFrmTransferVideo;
const
  colJudul    = 2;
  colJudul2   = 3;
  colArtis    = 4;
  colArtis2   = 5;
  colBahasa   = 6;
  colkategori = 7;
  colVol      = 8;
  colPath     = 1;

implementation

{$R *.dfm}

procedure TurboCopyFile(
  const
    SourceFile, (* the source file *)
    DestinationFile: String; (* destination file *)
  Display: PProgressbar (* this is a pointer to progress bar
    which we update if assigned,
    this procedure can be called without a
    progress bar like so:
    TurboCopyFile(Source, Destination, NIL); *)
  );
type
  (* define an array of 4096 bytes which holds the bytes *)
  TurboBuffer = array[1..4096] of Byte;
const
  (* we need to set the size of the buffer in a constant *)
  szBuffer = sizeof(TurboBuffer);
var
  (* File streams with which we work *)
  InStream,
  OutStream: TFileStream;
  (* we need this to store a logical operation's result *)
  CanCopy: Boolean;
  (* holds the number of bytes left when
     InStream.Size -InStream.Position < 4096 bytes *)
  BytesLeft: Integer;
  (* the Buffer almighty *)
  Buffer: TurboBuffer;
begin
  (* Open the source file so we can read it's bytes *)
  InStream := TFileStream.Create(SourceFile, fmOpenRead);
  (* create a new file to the desired destination *)
  OutStream := TFileStream.Create(DestinationFile, fmCreate);

  (* check if a progress bar was passed *)
  if Assigned(Display) then
    Display^.Max := InStream.Size;

  (* this is the operation I was talking about in the
     variable section, this checks if we can read a
     full buffer(4096 bytes) *)
  CanCopy :=
    (InStream.Size > InStream.Position) and
    ((InStream.Size -InStream.Position) >= szBuffer);

  (* this ensures that the progress bar is being painted *)
  Application.ProcessMessages;

  (* loop while we CanCopy *)
  while CanCopy do begin
    (* read 4096 bytes from source file *)
    InStream.ReadBuffer(Buffer, szBuffer);
    (* then write it to destination file *)
    OutStream.WriteBuffer(Buffer, szBuffer);
    (* check if display is assigned *)
    if Assigned(Display) then
      (* update it's position *)
      Display^.Position := InStream.Position;
    CanCopy :=
      (InStream.Size > InStream.Position) and
      ((InStream.Size -InStream.Position) >= szBuffer);
  end;

  (* store the number of bytes that is less than 4096 into
     a local variable *)
  BytesLeft := InStream.Size -InStream.Position;

  (* do we have some bytes left ? we don't care how many,
     we just know it's less than 4096 bytes *)
  if BytesLeft > 0 then begin
    (* surprise, or not we have some bytes left,
       read them all into the buffer *)
    InStream.ReadBuffer(Buffer, BytesLeft);
    (* write them to destination file *)
    OutStream.WriteBuffer(Buffer, BytesLeft);
  end;

  (* do we have a progress bar ? *)
  if Assigned(Display) then
    (* we do? then update it's progress *)
    Display^.Position := Display^.Max;

  (* free the memory *)
  FreeAndNil(InStream);
  FreeAndNil(OutStream);
end; (* end of TurboCopyFile *)


procedure TFrmTransferVideo.endProgress;
begin
  gauge.Value := 0;
end;

procedure TFrmTransferVideo.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  Action := caFree;
end;

procedure TFrmTransferVideo.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
begin
  if chan<>0 then
    alert('Tidak bisa keluar ketika video sedang diputar.!');
  CanClose := chan = 0;
end;

procedure TFrmTransferVideo.FormShow(Sender: TObject);
begin
  initForm;
end;

function TFrmTransferVideo.getAttrib: byte;
begin
if RBRight.Checked = true then
  Result := 2 else
if RBLeft.Checked  then
  Result := 1 else
  Result := 0;
end;

procedure TFrmTransferVideo.gridCanEditCell(Sender: TObject; ARow,
  ACol: Integer; var CanEdit: Boolean);
begin
  CanEdit := (ACol <> colVol+1) and (ACol <> colBahasa);
end;

procedure TFrmTransferVideo.gridGetEditorProp(Sender: TObject; ACol,
  ARow: Integer; AEditLink: TEditLink);
begin
  with grid do begin
    case ACol of
    colBahasa, colkategori :begin
        ClearComboString;
        if FileExists('lang.dat') then
          ComboBox.Items.LoadFromFile('lang.dat')
          else Alert('File lang.dat tidak ditemukan');
      end;
    colVol :begin
        ClearComboString;
        if FileExists('vol.dat') then
          ComboBox.Items.LoadFromFile('vol.dat')
          else Alert('File vol.dat tidak ditemukan');
      end;
    end;
  end;
end;

procedure TFrmTransferVideo.gridGetEditorType(Sender: TObject; ACol,
  ARow: Integer; var AEditor: TEditorType);
begin
  if (ACol in [colBahasa,colkategori,colVol]) then
    AEditor := edComboList;
end;

procedure TFrmTransferVideo.gridKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if key=vk_f2 then begin
    if grid.Col = colPath then
    begin
      if OD.Execute then
        grid.Cells[colPath, grid.Row] := OD.FileName;
    end;
  end;
//  if key=vk_delete then
//    grid.RemoveNormalRow(grid.Row);
end;

procedure TFrmTransferVideo.Hapus1Baris1Click(Sender: TObject);
begin
  if grid.Row = 1 then
  begin
//    initGrid;
    grid.ClearRows(grid.Row, 1);
  end
    else grid.RemoveNormalRow(grid.Row);
end;

procedure TFrmTransferVideo.HapusSemuaBaris1Click(Sender: TObject);
begin
  grid.RemoveRowsEx(1, grid.RowCount);
  initGrid;
end;

procedure TFrmTransferVideo.initForm;
begin
  initGrid;
  startProgress;
  Display.Position := 0;
  Panel1.SendToBack;
  grid.BringToFront;
end;

procedure TFrmTransferVideo.initGrid;
begin
  with Grid do
  begin
    Clear;
    RowCount := 2;
    FixedRows := 1;
    ColCount :=  colVol + 2;
    Cells[0, 0]           := 'No';
    Cells[colJudul, 0]    := 'Judul 1';
    Cells[colJudul2, 0]   := 'Judul 2';
    Cells[colArtis, 0]    := 'Artis 1';
    Cells[colArtis2, 0]   := 'Artis 2';
    Cells[colBahasa, 0]   := 'Bahasa';
    Cells[colkategori, 0] := 'Kategori';
    Cells[colVol, 0]      := 'Audio';
    Cells[colPath, 0]     := 'Pilih File Video (F2)';
    setColWidth;
  end;
end;

function TFrmTransferVideo.issaved: boolean;
begin

end;

function TFrmTransferVideo.isValid: boolean;
begin
Result:= False;
//  if CekInput(Result, RoomID.Text <> '', 'Kode Room belum diisi.', RoomID) then
  CekInput(Result, ServerDir.Text <> '', 'Direktori penyimpanan belum diisi.', ServerDir);
end;

procedure TFrmTransferVideo.PosisiLastChange(Sender: TObject);
begin
  xVideo_ChannelSetPosition(chan,Posisi.Value,xVideo_POS_SEC);
end;

procedure TFrmTransferVideo.prosessProgress(dataCount, progress: integer);
begin
  gauge.Value := Trunc( 100 / (dataCount /progress));
end;

procedure TFrmTransferVideo.RadioButton1Click(Sender: TObject);
begin
  xVideo_ChannelSetAttribute(chan,xVideo_ATTRIB_ChanProcess,getAttrib);
end;

procedure TFrmTransferVideo.RBLeftClick(Sender: TObject);
begin
  xVideo_ChannelSetAttribute(chan,xVideo_ATTRIB_ChanProcess,getAttrib);
end;

procedure TFrmTransferVideo.RBRightClick(Sender: TObject);
begin
    xVideo_ChannelSetAttribute(chan,xVideo_ATTRIB_ChanProcess,getAttrib);
end;

procedure TFrmTransferVideo.setColWidth;
begin
with grid do
begin
  AutoSize := True;
  ColWidths[colPath]      := 200;
  ColWidths[colJudul]     := 150;
  ColWidths[colJudul2]    := 100;
  ColWidths[colArtis]     := 100;
  ColWidths[colArtis2]    := 60;
  ColWidths[colBahasa]    := 0;
  ColWidths[colkategori]  := 100;
  ColWidths[colVol]       := 70;
end;
end;

procedure TFrmTransferVideo.startProgress;
begin
  gauge.Value := 0;
end;

procedure TFrmTransferVideo.Timer1Timer(Sender: TObject);
begin
  Posisi.Value := round(xVideo_ChannelGetPosition(chan,xVideo_POS_SEC));
end;

procedure TFrmTransferVideo.Volume1Change(Sender: TObject);
begin
  Timer1.Enabled:=False;
  xVideo_ChannelSetAttribute(chan,xVideo_ATTRIB_VOL,Volume1.Value);
  Timer1.Enabled:=True;
end;

procedure TFrmTransferVideo.btnPlayClick(Sender: TObject);
begin
  if chan<>0 then
  begin
   xVideo_StreamFree(chan);
   chan:=0;
  end;
  Chan :=xVideo_StreamCreateFile(PChar(grid.Cells[colPath, grid.Row]),0,
    {$IFDEF UNICODE}xVideo_UNICODE or xVideo_STREAM_AUTOFREE
    {$Else}xVideo_STREAM_AUTOFREE {$ENDIF});
  Posisi.MaxValue:=round(xVideo_ChannelGetLength(chan,xVideo_POS_SEC));
  xVideo_ChannelSetWindow(chan,Panel1.Handle);
  xVideo_ChannelSetAttribute(chan,xVideo_ATTRIB_ChanProcess,getAttrib);
  xVideo_ChannelPlay(chan);
end;

procedure TFrmTransferVideo.btnStopClick(Sender: TObject);
begin
  xVideo_ChannelStop(chan);
  xVideo_StreamFree(chan);
  chan := 0;
end;

procedure TFrmTransferVideo.btnTransferClick(Sender: TObject);
var i : integer;
    ADir, NamaFile: String;
begin
if isValid then
begin
  try
    btnStopClick(Sender);
    btnTransfer.Enabled := false;
    startProgress;
    for i := 1 to grid.RowCount do
    begin
      if (grid.Cells[colJudul, i] <> '') or
      (grid.Cells[colArtis, i] <> '') or
      (grid.Cells[colPath, i] <> '') or
      (grid.Cells[colBahasa, i] <> '') or
      (grid.Cells[colKategori, i] <> '') or
      (grid.Cells[colVol, i] <> '') or
      (grid.Cells[colPath, i] <> '') then
      begin
        Application.ProcessMessages;
        prosessProgress(grid.RowCount, i);

        NamaFile := grid.Cells[colJudul, i]+'#'+grid.Cells[colArtis, i]+'#'+grid.Cells[colKategori, i]+
        '#'+grid.Cells[colVol, i]+'.MPG';

        TurboCopyFile(grid.Cells[colPath, i], ServerDir.Text+ '\'+NamaFile , @Display);

        ExecSQL(DM.Buffer, 'insert into song_list (Judul,Judul2,artis,artis2,bahasa,jenis,volume,NamaFile,Direktori) '+
        'values ('+QuotedStr(grid.Cells[colJudul, i])+','+
        QuotedStr(grid.Cells[colJudul2, i])+','+
        QuotedStr(grid.Cells[colArtis, i])+','+
        QuotedStr(grid.Cells[colArtis2, i])+','+
        QuotedStr(grid.Cells[colKategori, i])+','+
        QuotedStr(grid.Cells[colKategori, i])+','+
        QuotedStr(LeftStr(grid.Cells[colVol, i],1))+','+
        QuotedStr(NamaFile)+','+
        QuotedStr(StringReplace(ServerDir.Text,'\','\\',[rfReplaceAll])+'\\') +')');
      end;
    end;
    Inform(MSG_SAVE_SUCCES);
    initForm;
  finally
    endProgress;
    btnTransfer.Enabled := true;
  end;
end;
end;

end.
